/**  ------------------------------ 数据解析及命令参数转换js插件开发说明 --------------------------------------------------------------
 * 一、约定：
 * 1.每一个设备类型对应一个js插件文件，文件位置：相对于springboot的resources目录下面的路径(/js/plugin/<devtype>.js);
 * 2.js插件文件名为<devtype>.js，devtype为设备类型编号，如：haitong_ac_v1;
 * 3.js插件中包括一个上报数据解析方法和N个（N>=0）控制命令转换方法。
 * 
 * 二、设备上报业务数据（metedata）解析：
 * 1、方法名固定为:funcupdataparse. 
 * 2、入参固定为:JSParam，定义参见com.zte.claa.inficombo.csa.app.service.jsplugin.JSParam，包括如下方法：
 *	(2.1) getDevtypeid() -->获取当前设备类型ID；
 *	(2.2) getDeveui()    -->获取对应设备编号deveui；
 *	(2.3) getDevport()   -->获取设备上报的port，通常用不到；
 *	(2.4) getParas()     -->获取指标映射表：Map<String, Object>，对于上报数据,只有一个参数项：uppayload，value是byte[]，终端上报的原始码流.
 *	(2.5) getPara(pname) -->获取指定名称的参数，返回Object对象；
 *  (2.6) getAppeui()    -->获取对应的appeui参数；
 * 3、解析结果分为四种情况：metedata或alarmdata或Map<String, Object>或null。
 * (3.1)如果是无效数据，则返回null;
 * (3.2)如果是metedata，则解析结果为json字符串，形如：{"f1name":f1val, "f2name":f2val, ...}，其中fnname和当前设备类型的业务模型定义一致；
 * (3.3)如果是告警AlarmData，则返回的对象为AlarmData对象，该java类型的定义参见:com.zte.claa.inficombo.csa.app.model.redis.AlarmData.
 * (3.4)如果上报的数据中同时包括metedata和alarm或需要返还ackcmd，则返回Map<String, Object>，map中包括最多5个item，分别是：
 *      (3.4.1)key="metedata", value=metedata对应的json字符串，和3.2一致；
 *      (3.4.2)key="alarm", value=AlarmData对象，和3.3一致。
 *      (3.4.3)key="ackcmd",value=AppCmdWrapper对象，详见com.zte.claa.inficombo.csa.app.service.rptparse.AppCmdWrapper定义.
 *      (3.4.4)key="metedatalist", value=ArrayList<String>, 列表item=metedata对应的json字符串，和3.2一致；
 *      (3.4.5)key="alarmlist", value=ArrayList<AlarmData>, 列表item=AlarmData对象，和3.3一致。
 * 
 * 三、控制指令转换说明：
 * 1、每一个命令控制字对应一个function，function名称=控制字名称;
 * 2、每一个控制字对应的func入参统一为jsParam，定义同数据解析，其中getParas()方法获取命令控制参数：
 * 	  (2.4) getParas(), 返回值：Map<String, Object>，key=[P1,....,Pn],val=P1~Pn对应的参数值；
 *    (2.5) getPara(pname) -->获取指定名称的参数，返回Object对象；
 * 3、控制命令转换结果为byte[]。
 * 	 
 * 四、js内部调试日志打印：
 *   var LogPrint = Java.type('com.zte.claa.inficombo.csa.app.service.rptparse.JsLogPrint');
 *   var logger = new LogPrint();
 *   logger.debug('debug-log');
 *   logger.info('info-log');
 *   logger.err('error log');
 *   
 * 转换时可以使用的jdk8所提供的各类java对象，通常是如下List对象；JSONObject是json转换对象类，参照本例使用。 
 *  
 *  ---------------------------------------------------------------------------------------------------------------------
 *  常用java类型引用：
 *  var ByteBuffer = Java.type('java.nio.ByteBuffer');
 *  var List = Java.type('java.util.ArrayList');
 *  var Map = Java.type('java.util.HashMap');
 *  var String = Java.type('java.lang.String');
 *  var JSONObject = Java.type('org.json.JSONObject');
 *  var DecimalFormat = Java.type('java.text.DecimalFormat');
 *  
 *  java.text.DecimalFormat df = new java.text.DecimalFormat("#.00");  
 *  df.format(你要格式化的数字);
 *  
 * 		buf.get(); 		// read 1 byte
		buf.getShort(); // read 2 bytes
		buf.getInt(); 	// read 4 bytes
		buf.getLong(); 	// read 8 bytes
 */ 

var ByteBuffer = Java.type('java.nio.ByteBuffer');
var List = Java.type('java.util.ArrayList');
var JavaString = Java.type('java.lang.String');
var Byte = Java.type('java.lang.Byte');
var JSONObject = Java.type('org.json.JSONObject');
var Map = Java.type('java.util.HashMap');
var Arrays = Java.type('java.util.Arrays');
var LogPrint = Java.type('com.zte.claa.inficombo.csa.app.service.rptparse.JsLogPrint');
var MultiPackageData = Java.type('com.zte.claa.inficombo.csa.app.service.rptparse.MultiPackageData');
var ConfDataRequest = Java.type('com.zte.claa.inficombo.csa.app.service.rptparse.ext.claa.ConfDataRequest');
var SensorOrgData = Java.type('com.zte.claa.inficombo.csa.app.service.rptparse.SensorOrgData');
var AppCommand = Java.type('com.zte.claa.inficombo.csa.app.service.rptparse.AppCommand');	
var AppCmdWrapper = Java.type('com.zte.claa.inficombo.csa.app.service.rptparse.AppCmdWrapper');
var AlarmData = Java.type('com.zte.claa.inficombo.csa.app.model.redis.AlarmData');
var DevVersionUpdateLog = Java.type('com.zte.claa.inficombo.csa.app.model.version.DevVersionUpdateLog');
var ClaaDevInitState = Java.type('com.zte.claa.inficombo.csa.app.model.dev.ClaaDevInitState');
var CRC16M = Java.type('com.zte.claa.inficombo.csa.app.service.rptparse.CRC16M');
var LocRawData = Java.type('com.zte.claa.inficombo.csa.app.service.rptparse.LocRawData');

/**
 * 1. 上报数据解析方法，统一固定命名为：funcupdataparse
 * 入参：JSParam
 * 
 * 克拉gsp设备，需要分包
 */
function funcupdataparse(jsParam){
	var upbs = jsParam.getPara('uppayload');
	var mpd = jsParam.getPara('multipkgdata');	
	var upbuf = ByteBuffer.wrap(upbs);	
	var json = new JSONObject();
	var logger = new LogPrint();	
	if(mpd == null){
		var mpd = new MultiPackageData();
		mpd.setIsConfirmed(1);
	}	
	var packbyte = upbuf.get() & 0x00FF;
	if((packbyte & 0x00F0) != 0x0000 && (packbyte & 0x00F0) != 0x00F0){
		return null;
	}
	
	if(0xF0 == packbyte){
		var outMap = new Map();
		mpd.setMultiPkgMode(2); //交叉多包模式
		var sensorid = upbuf.get() & 0x00FF;
		var sensorlen = upbuf.capacity()-2;
		mpd.setMsgtp(0xF0);
		var msgid = 0;
		var packnum = 1;
		var packseq = 0;
		logger.info("claa_gsp deal photo sensorid:"+sensorid+",msgtype:"+msgtype);
		var mpdbytes = []; 
		var itemid = 0x00;
		mpdbytes.push(itemid);
		mpdbytes.push(sensorlen & 0xFF);
		for(var idx=0; idx<sensorlen; idx++){
			mpdbytes.push(upbuf.get());
		}
		var result = mpd.appendData(sensorid,msgid,packnum,packseq+1, Java.to(mpdbytes, "byte[]"));
		outMap.put("multipkgdata", mpd);
		return outMap;
	}
	
	var msgver =  (packbyte>>4) & 0x0F;
	var msgid =  packbyte & 0x0F;	
	packbyte = upbuf.get();
	var packnum =  (packbyte>>4) & 0x0F;
	var packseq =  packbyte & 0x0F;		
	var packlen = upbuf.get() & 0x00FF;	
	if(upbuf.capacity()!=(packlen+3)){
		logger.info("Js parsed claa_gsp buffer failed:len cant match capacity");
		return null;
	}	
	logger.info("claa_gsp msgid:"+msgid+",msgver:"+msgver+",packnum:"+packnum+",packseq:"+packseq+",packlen:"+packlen+",upbuf.cap:"+upbuf.capacity());
	var msgtype = upbuf.get() & 0x00FF;
	mpd.setMsgtp(msgtype);
	var msgpdlen = 0;
	if(0x01 == msgtype || 0x02 == msgtype ||  0x03 == msgtype){
		msgpdlen = upbuf.get() & 0x00FF;
	}
	else if(0x10 == msgtype || 0x11 == msgtype){
		msgpdlen = packlen-1;
	}
	else if(0x51 == msgtype || 0x53 == msgtype || 0x55 == msgtype || 0x56 == msgtype){
		//升级消息
		msgpdlen = packlen-1;
	}
	else{
		logger.info("Js reparsed claa_gsp msgtype is invalid, msgtype:"+msgtype);
		return null;
	}
	
	var outMap = new Map();
	if(0x01 == msgtype){   //业务数据报文处理
		mpd.setMultiPkgMode(2); //交叉多包模式
		var sensorid = upbuf.get() & 0x00FF;
		var sordatalen = upbuf.get() & 0x00FF;
		logger.info("claa_gsp sensorid:"+sensorid+",sordatalen:"+sordatalen);
		var mpdbytes = []; 
		for(var idx=0; idx<sordatalen; idx++){
			mpdbytes.push(upbuf.get());
		}
		var result = mpd.appendData(sensorid,msgid,packnum,packseq+1, Java.to(mpdbytes, "byte[]"));
		outMap.put("multipkgdata", mpd);
		return outMap;
		
	}else if(0x03 == msgtype){   //心跳数据报文处理
		//mpd.setMultiPkgMode(0); //不能切换普通分包模式，影响业务报文收发
		outMap = ProcessReportGspHBFun(upbuf,jsParam.getDeveui());		
		var appwrapper = new AppCmdWrapper();
		var gsptimeseq = outMap.get("gsptimeseq");
		buildHeartBeatAckCmd(jsParam, appwrapper, gsptimeseq);
		outMap.put("ackcmd",appwrapper);
		return outMap;

	}else{    //配置请求，升级等报文处理
		mpd.setMultiPkgMode(0); //普通分包模式
		var mpdbytes = []; 
		for(var idx=0; idx<msgpdlen; idx++){
			mpdbytes.push(upbuf.get());
		}
		var result = mpd.appendData(packseq+1, Java.to(mpdbytes, "byte[]"));
		if(result == 1){
			logger.info("Js parsed claa_gsp data packseq repeated, getCurNum="+mpd.getCurNum());
			mpd.reInit();   //当接受数据不完整时，待确认是否直接清除，也可以讲部分数据进行解析，目前先不考虑，直接清除
			mpd.setIsConfirmed(1);
			mpd.appendData(packseq+1,mpdbytes);
		}
		var upbsstr = "";
		for(var idx=0; idx<mpdbytes.length; idx++){
			upbsstr += toHex(mpdbytes[idx] & 0x00FF)+" ";
		}
		logger.info("Js parsed claa_gsp:"+ upbsstr);
		mpd.setTotalNum(packnum);
		mpd.setIsParsed(0);	
		outMap.put("multipkgdata", mpd);
		return outMap;		
	}
	
	
}


function funcmultipkgreparse(mpd)
{	
    var json = new JSONObject();
    var logger = new LogPrint();	

	if(mpd == null)
	{
		return null;
	}	
	
	var msgver = mpd.getMsgver();
	
	var upbs = mpd.buildData();	
	var upbuf = ByteBuffer.wrap(upbs);
	
	
	var msgtype = mpd.getMsgtp();
	//var msgtype = upbuf.get() & 0x00FF;
	
	var upbsstr = "";
	for(var idx=0; idx<upbs.length; idx++)
	{
		upbsstr += toHex(upbs[idx] & 0x00FF)+" ";
	}
	
	//logger.info("Js reparsed claa_gsp msgtype:"+msgtype+",bytes:"+ Arrays.toString(upbs));
	logger.info("Js reparsed claa_gsp msgtype:"+msgtype+",upbsstr:"+ upbsstr);
	
    //消息类型0x10 配置总包数请求
	if(0x10 == msgtype)
	{
		var confdata = new ConfDataRequest();
		confdata.setDeveui(mpd.getDeveui());
		confdata.setAppeui(mpd.getAppeui());
		confdata.setProjectid(mpd.getProjectid());
		confdata.setReqflag(1);
		confdata.setDevport(0);
		confdata.setCmdcode("GspInitCmdPkgNumRsp");
		return confdata;		
	}
	//消息类型0x11 配置数据分包请求
	else if(0x11 == msgtype)
	{
		var packseq = upbuf.getShort() & 0x00FFFF;
		var confdata = new ConfDataRequest();
		confdata.setDeveui(mpd.getDeveui());
		confdata.setAppeui(mpd.getAppeui());
		confdata.setProjectid(mpd.getProjectid());
		confdata.setReqflag(0);
		confdata.setPkgindex(packseq);	
		return confdata;			
	}
	else if(0x01 == msgtype)  //数据消息上报
	{
		var outMap = null;
		outMap = ProcessReportDataFun(upbuf,mpd.getDeveui());
		return outMap;
	}
	else if(0x02 == msgtype)  //告警消息暂时不需要
	{
		var outMap = null;
		outMap = ProcessReportAlarmFun(upbuf,mpd.getDeveui());
		return outMap;
	}
	else if(0x03 == msgtype)  //GSP心跳消息上报
	{
		var outMap = null;
		
		outMap = ProcessReportGspHBFun(upbuf,mpd.getDeveui());
		
		var appwrapper = new AppCmdWrapper();
		var gsptimeseq = outMap.get("gsptimeseq");
		buildHeartBeatAckCmd(mpd, appwrapper, gsptimeseq);
		outMap.put("ackcmd",appwrapper);
		
		return outMap;
	}	
	else if(0x51 == msgtype){
		var state = upbuf.get() & 0x00FF;
		var devUpdataLog = new DevVersionUpdateLog();
		devUpdataLog.setRetbitmap("");
		devUpdataLog.setRetcode(0);
		devUpdataLog.setRemark("");
		if(0x00 == state){
			devUpdataLog.setRetcode(1);
			devUpdataLog.setRemark("Ready for upgrade!");
		}else if(0x01 == state){
			devUpdataLog.setRemark("Version is invalid!");
		}else if(0x02 == state){
			devUpdataLog.setRemark("Size of upgradefile is too large!");
		}else if(0x03 == state){
			devUpdataLog.setRemark("Parameters are not correct!");
		}
		return devUpdataLog;		
	}
	else if(0x53 == msgtype){
		var devUpdataLog = new DevVersionUpdateLog();		
		devUpdataLog.setRetcode(0);
		devUpdataLog.setRetbitmap("");
		devUpdataLog.setRemark("Cancel upgrade!");
		return devUpdataLog;
	}
	else if(0x55 == msgtype){
		var databyte = upbuf.get() & 0x00FF;
		var upDataResult = 0;
		var resBitmap = "";
		var resReason = "";
		
		var result = databyte & 0x0F;
		var repeatnum = upbuf.get() & 0x00FF;
		var lostpacksnum = upbuf.getShort() & 0x00FFFF;
		
		var crcflag = (databyte>>1) & 0x01;
		var packflag = (databyte>>2) & 0x01;
		var writeflag = (databyte>>3) & 0x01;
		if(0x00 == result){
			upDataResult = 3;
			resReason = "upgrade is successfull";
		}else{
			upDataResult = 4;
			if(0x01 == crcflag){
				resReason = "crc verification fail";			
			}
			if(0x01 == packflag){
				resReason = " and "+"file is incomplete";
			}
			if(0x01 == writeflag){
				resReason = " and "+"write upgradefile failed";
			}
		}
		
		resBitmap = "Round "+repeatnum+",lost "+lostpacksnum+" packages";
		
		var devUpdataLog = new DevVersionUpdateLog();
		devUpdataLog.setRetcode(upDataResult);
		devUpdataLog.setRetbitmap(resBitmap);
		devUpdataLog.setRemark(resReason);
		return devUpdataLog;
	}
	else if(0x56 == msgtype){
		var verlen = upbuf.get() & 0x00FF;	
		var initstate = new ClaaDevInitState();	 
		var softver = "";
		for(var idx=0; idx<verlen; idx++)
		{
			var bytetemp = upbuf.get();
			softver = softver+String.fromCharCode(bytetemp);
		}
		initstate.setVersion(softver);
		return initstate;
	}else if(0xF0 == msgtype){
		var outMap = null;
		outMap = ProcessReportPhotoFun(upbuf,mpd.getDeveui());
		return outMap;
	}
	else
	{
		logger.info("Js reparsed claa_gsp msgtype is invalid, msgtype:"+msgtype);
		return null;
	}
	
	return null;
}

function buildHeartBeatAckCmd(jsParam, appwrapper, gsptimeseq){
	appwrapper.setAppeui(jsParam.getAppeui());
	appwrapper.setDeveui(jsParam.getDeveui());
	appwrapper.setDevtypeid(jsParam.getDevtypeid());
	appwrapper.setConfirm(false);
	appwrapper.setPort(jsParam.getDevport());
	
	var appcmd =  new AppCommand();
	appcmd.setCmd("ReplyReportMsg");
	appcmd.appendPara("p1",gsptimeseq);
	appwrapper.setPayload(appcmd);
	return;
}

function getLocalTime(nS) {     
   return new Date(parseInt(nS) * 1000).toLocaleString().replace(/:\d{1,2}$/,' ');     
}   

function ReplyReportMsg(jsParam){
	var String = Java.type('java.lang.String');
	var cmdParaMap = jsParam.getParas();
	var timeseq = cmdParaMap.get("p1");
	var logger = new LogPrint();
	
	var nstimestamp=new Date().getTime();	
	var nonstimestamp = Math.floor(nstimestamp/1000);	
	nonstimestamp = nonstimestamp.toFixed(0);
	
	//nonstimestamplocal = nonstimestamp;
	
	nonstimestamp = nonstimestamp;
	
	if(nonstimestamp<0){
		nonstimestamp = 0;
	}
	
	var timebytearr = [];
	var databyte = new Byte(0);
	
	timebytearr.push(0x33);
	
	databyte = timeseq & 0xFF;	
	timebytearr.push(databyte);	
	
	databyte = (nonstimestamp>>24) & 0xFF;	
	timebytearr.push(databyte);
	databyte = (nonstimestamp>>16) & 0xFF;	
	timebytearr.push(databyte);
	databyte = (nonstimestamp>>8) & 0xFF;	
	timebytearr.push(databyte);	
	databyte = nonstimestamp & 0xFF;	
	timebytearr.push(databyte);	
	
	var realtime = getLocalTime(nonstimestamp);
	//logger.info("Js code claa_gsp time parameter realtime:"+realtime+",nonstimestamplocal:"+nonstimestamplocal+",nonstimestamp:"+nonstimestamp);
	logger.info("Js code claa_gsp time parameter realtime:"+realtime+",nonstimestamp:"+nonstimestamp);
	
	return Java.to(timebytearr, "byte[]");	
}

function ProcessReportDataFun(upbuf,deveui)
{
	var logger = new LogPrint();
	
	var outmap = new Map();
	var datalist = new List();
	
    //var datalen = upbuf.get() & 0x00FF;
 
    //logger.info("Js reparsed claa_gsp datalen:"+ datalen);
    
    var tmpmap = new Map();
	while(upbuf.hasRemaining())
	{	
		var sensorid = upbuf.get() & 0x00FF;
		var sordatalen = upbuf.get() & 0x00FF;
		var sordatabytes = null;
		if(null == tmpmap[sensorid])
		{
			var databytes = [];
			sordatabytes = databytes;
		}
		else
		{
			sordatabytes = tmpmap[sensorid];
		}
		
		for(var idx=0; idx<sordatalen; idx++)
		{
			sordatabytes.push(upbuf.get());
		}
		
		tmpmap.put(sensorid,sordatabytes);
	}
	
	for(var key in tmpmap)
	{
		var sensordata = new SensorOrgData();
		sensordata.setDtueui(deveui);
		sensordata.setSensorid(key);
		sensordata.setPayload(Java.to(tmpmap[key], "byte[]"));
		datalist.add(sensordata);
	}

	outmap.put("sensordatalist",datalist);
	
	return outmap;
}

function ProcessReportPhotoFun(upbuf,deveui)
{
	var logger = new LogPrint();
	
	var outmap = new Map();
	var datalist = new List();
	
    //var datalen = upbuf.get() & 0x00FF;
 
    //logger.info("Js reparsed claa_gsp datalen:"+ datalen);
    
    var tmpmap = new Map();
	while(upbuf.hasRemaining())
	{	
		var sensorid = upbuf.get() & 0x00FF;
		var sordatalen = upbuf.get() & 0x00FF;
		var sordatabytes = null;
		if(null == tmpmap[sensorid])
		{
			var databytes = [];
			sordatabytes = databytes;
		}
		else
		{
			sordatabytes = tmpmap[sensorid];
		}
		
		for(var idx=0; idx<sordatalen; idx++)
		{
			sordatabytes.push(upbuf.get());
		}
		
		tmpmap.put(sensorid,sordatabytes);
	}
	
	for(var key in tmpmap)
	{
		var sensordata = new SensorOrgData();
		sensordata.setDtueui(deveui);
		sensordata.setSensorid(key);
		sensordata.setPayload(Java.to(tmpmap[key], "byte[]"));
		datalist.add(sensordata);
	}

	outmap.put("sensordatalist",datalist);
	
	return outmap;
}

function ProcessReportAlarmFun(upbuf,deveui)
{
	return null;
}

function ProcessReportGspHBFun(upbuf,deveui)
{
	var logger = new LogPrint();
	var json = new JSONObject();	
	var outmap = new Map();
		
	var devpowerjson = new JSONObject();//终端电量信息	
	var locrawdata = new LocRawData();//定位消息对象	
		
    //var datalen = upbuf.get() & 0x00FF; 
    //logger.info("Js reparsed claa_gsp heartbeat datalen:"+ datalen);
    
	while(upbuf.hasRemaining())
	{	
		var statusbuf = upbuf.getShort();
		var isonline = statusbuf & 0x0001;
		var isactivegsp = (statusbuf>>1) & 0x0001;
		var isactiveslot1 = (statusbuf>>2) & 0x0001;
		var isactiveslot2 = (statusbuf>>3) & 0x0001;
		var isactiveslot3 = (statusbuf>>4) & 0x0001;
		var isactiveheartbeat = (statusbuf>>5) & 0x0001;
		var isgspconfsolid = (statusbuf>>6) & 0x0001;
		var isgprsiplock = (statusbuf>>9) & 0x0001;
		
		var errorbuf = upbuf.getShort();
		var errcompidslot1  = errorbuf & 0x0001;
		var errcompidslot2 = (errorbuf>>1) & 0x0001;
		var errcompidslot3 = (errorbuf>>2) & 0x0001;
		
		var gspofflinetimes = upbuf.getShort() & 0x00FFFF;
		var gspreboottimes = upbuf.getShort() & 0x00FFFF;
		var gspbatteryvolt = (upbuf.getShort() & 0x00FFFF)/100;
		gsptimeseq = (upbuf.get() & 0x00FF);

		json.put("isonline", isonline);
		json.put("isactivegsp", isactivegsp);
		json.put("isactiveslot1", isactiveslot1);
		json.put("isactiveslot2", isactiveslot2);
		json.put("isactiveslot3", isactiveslot3);
		
		//json.put("isactiveheartbeat", isactiveheartbeat);
		json.put("isgspconfsolid", isgspconfsolid);
		json.put("isgprsiplock", isgprsiplock);
		
		json.put("errcompidslot1", errcompidslot1);
		json.put("errcompidslot2", errcompidslot2);
		json.put("errcompidslot3", errcompidslot3);
		json.put("gspofflinetimes", gspofflinetimes);
		json.put("gspreboottimes", gspreboottimes);
		json.put("gspbatteryvolt", gspbatteryvolt);
		
		//构造电量管理数据
		devpowerjson.put("curvoltage", gspbatteryvolt);
		locrawdata.addDevPowerData(devpowerjson.toString());
		logger.info("Js parsed claa_gsp devpowerjson:" + devpowerjson.toString());
		
		logger.info("Js parsed gsp heartbeat metedata:"+json.toString());
		
		outmap.put("metedata",json.toString());
		outmap.put("gsptimeseq",gsptimeseq);
		outmap.put("locrawdata", locrawdata);
		
		return outmap;
	}
	
}



function GspInitCmdPkgNumRsp(jsParam)
{
	var cmdParaMap = jsParam.getParas();
	var pkgnum = cmdParaMap.get("pkgnum");
	
	var ret = [];
	
	var highbyte = new Byte(0); 
	highbyte = (pkgnum>>8) & 0xFF;
	
	var lowbyte = new Byte(0); 
	lowbyte = pkgnum & 0xFF;
	
	ret.push(0x10);
	ret.push(highbyte);
	ret.push(lowbyte);
	
	return Java.to(ret, "byte[]");	
	
}

//GSP控制命令
function SetGspControl(jsParam){
	var cmdParaMap = jsParam.getParas();
	var slot0status = cmdParaMap.get("slot0status");
	var slot1status = cmdParaMap.get("slot1status");
	var slot2status = cmdParaMap.get("slot2status");
	var gspreboot = cmdParaMap.get("gspreboot");
	var gspreconf = cmdParaMap.get("gspreconf");
	var gspconfsolid = cmdParaMap.get("gspconfsolid");
	var gprsiplock = cmdParaMap.get("gprsiplock");
	
	
	var logger = new LogPrint();	
	
	var head = [];
	var data = [];
	var ret = [];
	
	head.push(0x32);	
	
	logger.info("SetGspControl js paras slot0status:" + slot0status);	
	var databyte = new Byte(0);
	if(slot0status == 0 || slot0status == 1)
	{        
		databyte = slot0status & 0xFF;
	}
	else
	{
		databyte = 0x02 & 0xFF;
	}
	data.push(databyte);
	
	logger.info("SetGspControl js paras slot1status:" + slot1status);	
	if(slot1status == 0 || slot1status == 1)
	{        
		databyte = slot1status & 0xFF;
	}
	else
	{
		databyte = 0x02 & 0xFF;
	}	
	data.push(databyte);
	
	logger.info("SetGspControl js paras slot2status:" + slot2status);
	if(slot2status == 0 || slot2status == 1)
	{        
		databyte = slot2status & 0xFF;
	}
	else
	{
		databyte = 0x02 & 0xFF;
	}	
    data.push(databyte);
	
    logger.info("SetGspControl js paras gspreboot:" + gspreboot);
	if(gspreboot == 1)
	{        
		databyte = gspreboot & 0xFF;
	}
	else
	{
		databyte = 0x02 & 0xFF;
	}	
    data.push(databyte);
    
    logger.info("SetGspControl js paras gspreconf:" + gspreconf);
	if(gspreconf == 1)
	{        
		databyte = gspreconf & 0xFF;
	}
	else
	{
		databyte = 0x02 & 0xFF;
	}	
    data.push(databyte);
    
    logger.info("SetGspControl js paras gspconfsolid:" + gspconfsolid);
	if(gspconfsolid == 0 || gspconfsolid == 1)
	{        
		databyte = gspconfsolid & 0xFF;
	}
	else
	{
		databyte = 0x02 & 0xFF;
	}	
    data.push(databyte);
    
    logger.info("SetGspControl js paras gprsiplock:" + gprsiplock);
	if(gprsiplock == 0 || gprsiplock == 1)
	{        
		databyte = gprsiplock & 0xFF;
	}
	else
	{
		databyte = 0x02 & 0xFF;
	}	
    data.push(databyte);
        
    for(var idx=0; idx<9; idx++)
    {
    	data.push(0x00);
    }
	
	ret = head.concat(data);
	
	return Java.to(ret, "byte[]");		
}

function DevVerUpdPrepare(jsParam){
	var cmdParaMap = jsParam.getParas();
	var keyend = cmdParaMap.get("keyend");
	var bcatfreq = cmdParaMap.get("bcatfreq");
	var dr = cmdParaMap.get("dr");
	var ch = cmdParaMap.get("ch");
	var starttime = cmdParaMap.get("starttime");
	var runtime = cmdParaMap.get("runtime");
	var filesize = cmdParaMap.get("filesize");
	var blocknum = cmdParaMap.get("blocknum");
	var filename = cmdParaMap.get("filename");
	var crc32 = cmdParaMap.get("crc32");
	var repeatnum = cmdParaMap.get("repeatnum");
	var interval = cmdParaMap.get("interval");
	
	var logger = new LogPrint();
	var head = [];
	var confdata = [];
	var ret = [];
	var confdatalen = 0;
	var databyte = new Byte(0);
	
	head.push(0x50);
	
	logger.info("Js paras keyend:" + keyend);
	if(keyend != null)
	{      
		// keyend = keyend.toFixed(0);
		databyte = keyend & 0xFF;
		confdata.push(databyte);
		confdatalen += 1;
	}
	else
	{
		return null;
	}	
	
	/*
	logger.info("Js paras bcatfreq:" + bcatfreq);
	if(bcatfreq != null)
	{   
		bcatfreq = bcatfreq*10;  //终端频率单位100KHZ
		bcatfreq = bcatfreq.toFixed(0);
		databyte = bcatfreq>>8 & 0xFF;
		confdata.push(databyte); 
		databyte = bcatfreq & 0xFF;
		confdata.push(databyte); 
		confdatalen += 2;
	}
	else
	{
		return null;
	}	
	*/
	
	logger.info("Js paras ch:" + ch);
	if(ch != null)
	{   
		ch = ch.toFixed(0);
		databyte = ch & 0xFF;
		confdata.push(databyte); 
		confdatalen += 1;
	}
	else
	{
		return null;
	}
	
	logger.info("Js paras dr:" + dr);
	if(dr != null)
	{        
		dr = dr.toFixed(0);
		databyte = dr & 0xFF;
		confdata.push(databyte); 
		confdatalen += 1;
	}
	else
	{
		return null;
	}	
	
	logger.info("Js paras starttime:" + starttime);
	if(starttime != null)
	{   
		starttime = starttime.toFixed(0);
		databyte = starttime>>24 & 0xFF;
		confdata.push(databyte); 		
		databyte = starttime>>16 & 0xFF;
		confdata.push(databyte); 		
		databyte = starttime>>8 & 0xFF;
		confdata.push(databyte); 
		databyte = starttime & 0xFF;
		confdata.push(databyte); 
		confdatalen += 4;
	}
	else
	{
		return null;
	}
	
	logger.info("Js paras repeatnum:" + repeatnum);
	if(runtime != null)
	{   
		repeatnum = repeatnum.toFixed(0);
		databyte = repeatnum & 0xFF;
		confdata.push(databyte); 	
		confdatalen += 1;
	}
	else
	{
		return null;
	}
	
	logger.info("Js paras interval:" + interval);
	if(interval != null)
	{   
		interval = interval/60;
		interval = interval.toFixed(0);
		databyte = interval & 0xFF;
		confdata.push(databyte); 	
		confdatalen += 1;
	}
	else
	{
		return null;
	}
	
	logger.info("Js paras filesize:" + filesize);
	if(filesize != null)
	{   
		filesize = filesize.toFixed(0);		
		databyte = filesize>>16 & 0xFF;
		confdata.push(databyte); 		
		databyte = filesize>>8 & 0xFF;
		confdata.push(databyte); 
		databyte = filesize & 0xFF;
		confdata.push(databyte); 
		confdatalen += 3;
	}
	else
	{
		return null;
	}
	
	logger.info("Js paras blocknum:" + blocknum);
	if(blocknum != null)
	{   
		blocknum = blocknum.toFixed(0);				
		databyte = blocknum>>8 & 0xFF;
		confdata.push(databyte); 
		databyte = blocknum & 0xFF;
		confdata.push(databyte); 
		confdatalen += 2;
	}
	else
	{
		return null;
	}
	
	logger.info("Js paras filename:" + filename);
	if(filename != null)
	{   
		if(filename.length > 15){
			return null;
		}
		
		for(var i=0; i<15; i++){
			if(i<filename.length){
		        var str = filename.charAt(i);
		        var charcode= str.charCodeAt();
				databyte = charcode & 0xFF;
				confdata.push(databyte); 				
			}else{
				confdata.push(0x00); 
			}

		}
		confdatalen += 15;
		
	}
	else
	{
		return null;
	}	
	
	/*
	logger.info("Js paras crc32:" + crc32);
	confdata.push(0x64);	
	confdatalen += 1;
	if(crc32 != null)
	{   
		crc32 = crc32.toFixed(0);
		//crc32 = parseInt(crc32,16);
		confdata.push(0x02);
		databyte = crc32>>8 & 0xFF;		
		confdata.push(databyte); 
		databyte = crc32 & 0xFF;
		confdata.push(databyte); 
		confdatalen += 3;
	}
	else
	{
		return null;
	}
	*/
	
	//head.push(confdatalen);
	
	ret = head.concat(confdata);
	
	return Java.to(ret, "byte[]");
	
}

function DevVerUpdCancel(jsParam){
	var cmdParaMap = jsParam.getParas();
	var logger = new LogPrint();
	var ret = [];
	
	ret.push(0x52);
	
	return Java.to(ret, "byte[]");
}


function DevVerBlockSent(jsParam){
	var cmdParaMap = jsParam.getParas();
	var seqno = cmdParaMap.get("seqno");
	var blockdata = cmdParaMap.get("blockdata");
	
	var logger = new LogPrint();
	var head = [];
	var confdata = [];
	var ret = [];
	var confdatalen = 0;
	var databyte = new Byte(0);
	
	head.push(0x54);
	
	logger.info("Js paras seqno:" + seqno);
	if(seqno != null)
	{   
		databyte = seqno>>8 & 0xFF;
		confdata.push(databyte); 
		databyte = seqno & 0xFF;
		confdata.push(databyte); 
		confdatalen += 2;
	}
	else
	{
		return null;
	}	
	
	if(blockdata != null)
	{   
		var blocklen = blockdata.length;
		var byteslen = blocklen/2;
		if(blocklen%2 != 0){
			return null;
		}
		confdata.push(byteslen);
		confdatalen += 1;
		
		for(var i=0; i<byteslen;i++){
			var bytestr = blockdata.substring(i*2,2*i+2)
			var databyte = parseInt(bytestr,16);
			confdata.push(databyte); 
			confdatalen += 1;
		}
	}
	else
	{
		return null;
	}	
	
	//head.push(confdatalen);
	
	ret = head.concat(confdata);
	return Java.to(ret, "byte[]");
}


function DevRelayControl(jsParam){
	var cmdParaMap = jsParam.getParas();
	var relay1state = cmdParaMap.get("relay1state");
	var relay2state = cmdParaMap.get("relay2state");
	var logger = new LogPrint();
	var confdata = [];
	var confdatalen = 0;
	var databyte = new Byte(0);
	
	confdata.push(0x35);
	
	logger.info("Js paras relay1state:" + relay1state);
	if(relay1state!=null && (relay1state==0 || relay1state==1 || relay1state==2))
	{   
		databyte = relay1state & 0xFF;
		confdata.push(databyte); 
		confdatalen += 1;
	}
	else
	{
		return null;
	}	
	
	logger.info("Js paras relay2state:" + relay2state);
	if(relay2state!=null && (relay2state==0 || relay2state==1 || relay2state==2))
	{   
		databyte = relay2state & 0xFF;
		confdata.push(databyte); 
		confdatalen += 1;
	}
	else
	{
		return null;
	}
	
	return Java.to(confdata, "byte[]");
}

function SetWhiteList(jsParam){
	var cmdParaMap = jsParam.getParas();
	var slotid = cmdParaMap.get("slotid");
	var opertype = cmdParaMap.get("opertype");
	var nametype = cmdParaMap.get("nametype");
	var namesize = cmdParaMap.get("namesize");
	var namelist = cmdParaMap.get("namelist");
	var logger = new LogPrint();
	var confdata = [];
	var confdatalen = 0;
	var databyte = new Byte(0);	
	confdata.push(0x34);
	
	logger.info("Js paras slotid:" + slotid);
	if(slotid!=null && (slotid==0 || slotid==1 || slotid==2))
	{   
		databyte = slotid & 0xFF;
		confdata.push(databyte); 
		confdatalen += 1;
	}
	else
	{
		return null;
	}	
	
	logger.info("Js paras opertype:" + opertype);
	databyte = 0x00;
	if(opertype!=null && (opertype==0 || opertype==1 || opertype==2)){   
		if(opertype==1){
			databyte = databyte | 0x10;
		}else if(opertype==2){
			databyte = databyte | 0x20;
			confdata.push(databyte); 
			return Java.to(confdata, "byte[]");
		}
	}
	else{
		return null;
	}
	
	logger.info("Js paras nametype:" + nametype);
	if(nametype!=null && (nametype==0 || nametype==1 || nametype==2)){
		if(nametype==1){
			databyte = databyte | 0x01;
		}else if(nametype==2){
			databyte = databyte | 0x02;
		}
	}
	else{
		return null;
	}
	confdata.push(databyte); 
	confdatalen += 1;
	
	logger.info("Js paras namesize:" + namesize);
	if(namesize!=null && namesize<=10){   
		databyte = namesize & 0xFF;
		confdata.push(databyte); 
		confdatalen += 1;
	}
	else{
		return null;
	}	
	
	logger.info("Js paras namelist:" + namelist);
	if(namesize!=null && namelist.length==namesize*8){   
		var namelistbytes = CRC16M.toBytes(namelist);
		for(var idx=0; idx<namesize*4; idx++){
			confdata.push(namelistbytes[idx]);
			confdatalen += 1;
		}
	}
	else{
		return null;
	}		

	return Java.to(confdata, "byte[]");
}

function DevVerBlkSendFinished(jsParam){
	var cmdParaMap = jsParam.getParas();
	var logger = new LogPrint();
	var ret = [];	
	ret.push(0x57);	
	return Java.to(ret, "byte[]");
}

//将一个数字转化成16进制字符串形式
function toHex(num){
	return num<16?"0"+num.toString(16):num.toString(16);
}
